package com.gin.kotlin.no_gay_alliance.activity.replyhistory

import android.app.DatePickerDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.RadioGroup
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.StringRes
import androidx.core.widget.addTextChangedListener
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.activity.AbstractPagerListActivity
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.ReplyHistoryArgument
import com.gin.kotlin.no_gay_alliance.base.AbstractBindingFragment
import com.gin.kotlin.no_gay_alliance.base.AlertDialogUtils
import com.gin.kotlin.no_gay_alliance.base.InputMethodUtils
import com.gin.kotlin.no_gay_alliance.database.dao.ReplyHistoryDao
import com.gin.kotlin.no_gay_alliance.databinding.ActivityReplyHistoryBinding
import com.gin.kotlin.no_gay_alliance.fragment.replyhistory.ReplyHistoryPageHtmlFragment
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils
import com.gin.kotlin.no_gay_alliance.webview.BbsCodeWebViewPool
import com.gin.nga.utils.MathUtils
import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime

class ReplyHistoryActivity : AbstractPagerListActivity<ActivityReplyHistoryBinding>(), TextView.OnEditorActionListener, RadioGroup.OnCheckedChangeListener {
    private lateinit var dao: ReplyHistoryDao
    private lateinit var argument: ReplyHistoryArgument
    lateinit var bbsCodeWebViewPool: BbsCodeWebViewPool
    override fun refresh() {
        doSearch()
    }

    override fun launchPostActivity(launcher: ActivityResultLauncher<Intent>) {}

    override fun onCreate() {
        // 正文WebView池
        this.bbsCodeWebViewPool = BbsCodeWebViewPool(this)


        val b = this.b ?: return
        this.dao = App.INSTANCE.database.replyHistoryDao()

        // 配置关键字输入框
        b.etKeyword.also { et ->
            et.setOnEditorActionListener(this)
            et.requestFocus()
            InputMethodUtils.show(et, this)

            // 修改时联动修改参数
            et.addTextChangedListener(object : TextWatcher {
                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                }

                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                    argument = argument.copy(keyword = s.toString())
                }

                override fun afterTextChanged(s: Editable?) {
                }
            })
        }
        // 配置搜索条件
        // 用户名
        b.etUsername.also { et ->
            et.setText(argument.username)
            et.addTextChangedListener { argument = argument.copy(username = it.toString()) }
            et.setOnEditorActionListener(this)
        }

        b.radioGroupHasImage.also { rg ->
            rg.check(
                when (argument.hasImage) {
                    true -> R.id.radio_button_has_image_true
                    false -> R.id.radio_button_has_image_false
                    null -> R.id.radio_button_has_image_unknown
                }
            )
            rg.setOnCheckedChangeListener(this)
        }

        b.radioGroupAnonymous.also { rg ->
            rg.check(
                when (argument.anonymous) {
                    true -> R.id.radio_button_anonymous_true
                    false -> R.id.radio_button_anonymous_false
                    null -> R.id.radio_button_anonymous_unknown
                }
            )
            rg.setOnCheckedChangeListener(this)
        }


        // 时间范围
        b.tvTimeStart.also { tv ->
            // 初始化
            textViewSetTime(tv, R.string.tv_time_start, argument.start?.let { ZonedDateTime.ofInstant(Instant.ofEpochSecond(it), ZoneId.systemDefault()) })

            // 参数中的时间或当前时间
            tv.setOnClickListener { v ->
                val textView = v as TextView
                val zdt = argument.start?.let { ZonedDateTime.ofInstant(Instant.ofEpochSecond(it), ZoneId.systemDefault()) } ?: ZonedDateTime.now()
                // 日期选择弹窗
                DatePickerDialog(this, null, zdt.year, zdt.monthValue - 1, zdt.dayOfMonth).also { dialog ->
                    // 设置日期
                    dialog.setOnDateSetListener { _, year, month, dayOfMonth ->
                        val time = ZonedDateTime.of(year, month + 1, dayOfMonth, 0, 0, 0, 0, ZoneId.systemDefault())
                        argument = argument.copy(start = time.toEpochSecond())
                        textViewSetTime(textView, R.string.tv_time_start, time)
                    }
                    // 清空按钮
                    dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "清空") { _, _ ->
                        argument = argument.copy(start = null)
                        textViewSetTime(textView, R.string.tv_time_start)
                    }
                    dialog.show()
                }
            }
        }
        b.tvTimeEnd.also { tv ->
            // 初始化
            textViewSetTime(tv, R.string.tv_time_end, argument.end?.let { ZonedDateTime.ofInstant(Instant.ofEpochSecond(it), ZoneId.systemDefault()) })

            // 参数中的时间或当前时间
            tv.setOnClickListener { v ->
                val textView = v as TextView
                val zdt = argument.end?.let { ZonedDateTime.ofInstant(Instant.ofEpochSecond(it), ZoneId.systemDefault()) } ?: ZonedDateTime.now()
                // 日期选择弹窗
                DatePickerDialog(this, null, zdt.year, zdt.monthValue - 1, zdt.dayOfMonth).also { dialog ->
                    // 设置日期
                    dialog.setOnDateSetListener { _, year, month, dayOfMonth ->
                        val time = ZonedDateTime.of(year, month + 1, dayOfMonth, 23, 59, 59, 0, ZoneId.systemDefault())
                        argument = argument.copy(end = time.toEpochSecond())
                        textViewSetTime(textView, R.string.tv_time_end, time)
                    }
                    // 清空按钮
                    dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "清空") { _, _ ->
                        argument = argument.copy(end = null)
                        textViewSetTime(textView, R.string.tv_time_end)
                    }
                    dialog.show()
                }
            }
        }


    }

    /**
     * 设置一个 TextView 的文本内容为指定日期,如果日期为空则显示默认文本
     * @param textView TextView
     * @param resId Int
     * @param zdt ZonedDateTime?
     */
    private fun textViewSetTime(textView: TextView, @StringRes resId: Int, zdt: ZonedDateTime? = null) {
        textView.text = zdt?.let { TimeUtils.DATE_FORMATTER_YEAR_DAY.format(it) } ?: getString(resId)
    }

    override fun onResume() {
        super.onResume()
        setToolbarTitle("回复历史查询")
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.mi_search -> {
                doSearch()
                true

            }
            // 切换搜索条件显示状态
            R.id.mi_filter -> {
                val layoutFilter = b?.layoutFilter
                if (layoutFilter == null)
                    false
                else {
                    layoutFilter.visibility = if (layoutFilter.visibility == View.GONE) View.VISIBLE else View.GONE
                    true
                }
            }
            // 功能说明
            R.id.mi_info -> {
                val message = listOf(
                    "选择时间范围、是否含图片、是否匿名可以提高查询速度",
                    "点击用户名可跳转用户中心",
                    "点击发布和修改时间、楼层号可跳转目标回复",
                    "点击主题标题可跳转主题",
                )

                AlertDialogUtils.builder(this, "功能说明", message.joinToString("\n")).show()
                true
            }

            else -> false
        }
    }

    /**
     * 执行搜索
     */
    private fun doSearch() {
        val b = this.b ?: return

        // 隐藏搜索条件
        b.layoutFilter.visibility = View.GONE

        InputMethodUtils.hide(b.etKeyword, this)

        Log.i(TAG, "执行搜索: ${AbstractBindingFragment.mapper.writeValueAsString(this.argument)}")

        // 总记录条数
        val total = dao.count(argument.buildSql("select count(1) as count from ReplyHistory where %s"))
        if (total == 0) {
            toast("未找到匹配数据")
            return
        }
        Log.i(TAG, "查询到记录数: $total")
        val totalPage = MathUtils.getTotalPage(total, argument.size) ?: 1
        updatePage(1, totalPage)

        // 适配器
        b.viewPager2.adapter = object : FragmentStateAdapter(this) {
            override fun getItemCount() = totalPage
            override fun createFragment(position: Int) = ReplyHistoryPageHtmlFragment.newInstance(argument.copy(page = position + 1))
        }
    }

    override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, menuInflater)
        menuInflater.inflate(R.menu.info, menu)
        menuInflater.inflate(R.menu.filter, menu)
        menuInflater.inflate(R.menu.search, menu)
    }

    override fun handleIntent(intent: Intent) {
        this.argument = parseArgument(intent, ReplyHistoryArgument::class.java.simpleName, ReplyHistoryArgument::class.java)
    }


    override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
        // 当按下软键盘搜索键时，执行搜索
        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
            // 执行搜索
            doSearch()
            return true
        }
        return false
    }

    override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
        when (checkedId) {
            R.id.radio_button_has_image_true -> argument = argument.copy(hasImage = true)
            R.id.radio_button_has_image_false -> argument = argument.copy(hasImage = false)
            R.id.radio_button_has_image_unknown -> argument = argument.copy(hasImage = null)
            R.id.radio_button_anonymous_true -> argument = argument.copy(anonymous = true)
            R.id.radio_button_anonymous_false -> argument = argument.copy(anonymous = false)
            R.id.radio_button_anonymous_unknown -> argument = argument.copy(anonymous = null)
        }
    }

    companion object {
        @JvmStatic
        fun start(context: Context, argument: ReplyHistoryArgument) =
            context.startActivity(Intent(context, ReplyHistoryActivity::class.java).putExtra(ReplyHistoryArgument::class.java.simpleName, argument))
    }
}